package com.luo.d3s.ext.data.permission.dto.context;

import com.luo.d3s.ext.data.permission.dto.context.base.BaseDpDto;
import com.luo.d3s.ext.data.permission.dto.context.base.BaseUserDto;
import com.luo.d3s.ext.data.permission.util.DpUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * 用户数据权限DTO
 *
 * @author luohq
 * @date 2023-06-20 10:37
 */
public class UserSupplierDto implements BaseUserDto {

    /**
     * 用户ID（通常对应当前登录用户ID）
     */
    private Supplier<String> userIdSupplier;

    /**
     * 用户所在部门或所属组织（通常对应登录用户的组织部门ID）
     */
    private Supplier<String> deptIdSupplier;

    /**
     * 前用户所属的部门及子部门ID集合
     */
    private Supplier<Collection<String>> deptAndChildDeptIdsSupplier;

    /**
     * 用户数据权限集合
     */
    private Supplier<Collection<BaseDpDto>> dataPermissionsSupplier;

    /**
     * 额外的参数
     */
    private Supplier<Map<String, String>> additionalParamsSupplier;

    public UserSupplierDto() {
    }

    public UserSupplierDto(Supplier<Object> userIdSupplier, Supplier<Object> deptIdSupplier, Supplier<Collection<?>> deptAndChildDeptIdsSupplier, Supplier<Collection<BaseDpDto>> dataPermissionsSupplier) {
        this.setUserIdSupplier(userIdSupplier);
        this.setDeptIdSupplier(deptIdSupplier);
        this.setDeptAndChildDeptIdsSupplier(deptAndChildDeptIdsSupplier);
        this.setDataPermissionsSupplier(dataPermissionsSupplier);
    }

    public static UserSupplierDto ofUserAndDept(Supplier<Object> userIdSupplier, Supplier<Object> deptIdSupplier) {
        return new UserSupplierDto(userIdSupplier, deptIdSupplier, null, null);
    }

    public static UserSupplierDto ofUserDeptAndDataPermissions(Supplier<Object> userIdSupplier, Supplier<Object> deptIdSupplier, Supplier<Collection<BaseDpDto>> dataPermissionsSupplier) {
        return new UserSupplierDto(userIdSupplier, deptIdSupplier, null, dataPermissionsSupplier);
    }

    public static UserSupplierDto ofAll(Supplier<Object> userIdSupplier, Supplier<Object> deptIdSupplier, Supplier<Collection<?>> deptAndChildDeptIdsSupplier, Supplier<Collection<BaseDpDto>> dataPermissionsSupplier) {
        return new UserSupplierDto(userIdSupplier, deptIdSupplier, deptAndChildDeptIdsSupplier, dataPermissionsSupplier);
    }

    public static UserSupplierDto fromProp(UserPropDto userPropDto) {
        if (Objects.isNull(userPropDto)) {
            return null;
        }
        return new UserSupplierDto(
                userPropDto::getUserId,
                userPropDto::getDeptId,
                userPropDto::getDeptAndChildDeptIds,
                userPropDto::getDataPermissions
        );
    }

    public void setUserIdSupplier(Supplier<Object> userIdSupplier) {
        this.userIdSupplier = DpUtils.convertObjToStringSupplier(userIdSupplier);
    }

    @Override
    public String getUserId() {
        return DpUtils.getSupplierValue(this.userIdSupplier, null);
    }

    public void setDeptIdSupplier(Supplier<Object> deptIdSupplier) {
        this.deptIdSupplier = DpUtils.convertObjToStringSupplier(deptIdSupplier);
    }

    @Override
    public String getDeptId() {
        return DpUtils.getSupplierValue(this.deptIdSupplier, null);
    }

    @Override
    public Collection<String> getDeptAndChildDeptIds() {
        return DpUtils.getSupplierValue(deptAndChildDeptIdsSupplier, Collections.emptySet());
    }

    public void setDeptAndChildDeptIdsSupplier(Supplier<Collection<?>> deptAndChildDeptIdsSupplier) {
        this.deptAndChildDeptIdsSupplier = DpUtils.convertObjToStringCollectionSupplier(deptAndChildDeptIdsSupplier);
    }

    public void setDataPermissionsSupplier(Supplier<Collection<BaseDpDto>> dataPermissionsSupplier) {
        this.dataPermissionsSupplier = dataPermissionsSupplier;
    }

    @Override
    public Collection<BaseDpDto> getDataPermissions() {
        return DpUtils.getSupplierValue(this.dataPermissionsSupplier, Collections.emptySet());
    }

    public void setAdditionalParamsSupplier(Supplier<Map<String, String>> additionalParamsSupplier) {
        this.additionalParamsSupplier = additionalParamsSupplier;
    }

    @Override
    public Map<String, String> getAdditionalParams() {
        return DpUtils.getSupplierValue(this.additionalParamsSupplier, Collections.emptyMap());
    }

    @Override
    public String toString() {
        return "UserSupplierDto{" +
                "userIdSupplier=" + userIdSupplier +
                ", deptIdSupplier=" + deptIdSupplier +
                ", deptAndChildDeptIdsSupplier=" + deptAndChildDeptIdsSupplier +
                ", dataPermissionsSupplier=" + dataPermissionsSupplier +
                ", additionalParamsSupplier=" + additionalParamsSupplier +
                '}';
    }
}
